package cn.tedu.rms.message;

import cn.tedu.rms.base.util.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;

import java.util.Date;
import java.util.UUID;

@Slf4j
public class WebSocketCheckJob implements Job {


    /**
     * 必须有无参构造器，否则抛异常 NoSuchMethodException
     */
    public WebSocketCheckJob() {

    }

    public WebSocketCheckJob(Long userId) {
        //1.创建调度器工厂
        StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();

        try {
            //2.获取调度器Scheduler实例
            Scheduler scheduler = schedulerFactory.getScheduler();

            boolean existJob = isExistJob(userId, scheduler);
            if(existJob){
                log.debug("用户：{}，断开连接任务已存在，不在创建",userId);
            }else{
                //3.创建定时任务
                // 定义一个JobDetail，它包含了要执行的Job的类名等信息
                // Quartz 在实例化任务时会使用反射来调用这个构造器，因此需要有无参构造器
                JobDetail jobDetail = JobBuilder.newJob(WebSocketCheckJob.class)
                        //.withIdentity("websocket-check-job" + UUID.randomUUID(), "websocket-check-job-group")
                        .withIdentity("websocket-check-job" + userId, "websocket-check-job-group")//一个用户只能创建一个定时任务
                        .usingJobData("userId",userId)
                        .build();
                long now = System.currentTimeMillis();
                long deviceCheckTime = now + 5 * 60 * 1000;
                Date triggerTime = new Date(deviceCheckTime);
                log.debug("断开用户连接任务将在当前时间{}的5分钟后{}开始执行", new Date(now), triggerTime);

                //4.定义触发器
                Trigger trigger = TriggerBuilder.newTrigger()
                        .startAt(triggerTime)
                        .build();

                //5.调度器将任务和触发器进行绑定
                scheduler.scheduleJob(jobDetail, trigger);
                //6.启动调度器
                scheduler.start();
            }



        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        //listAllJobs();

    }

    /**
     * 调度器调用这个方法执行具体业务
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.debug("断开用户连接任务在规定时间(5分钟后)执行");
        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        Long userId = jobDataMap.getLong("userId");
        SpringContextUtils.getBean(WebSocketServer.class).disconnectUser(userId);

    }


    /**
     * 查看所有已有的JobDetail
     */
    public static void listAllJobs() {
        StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
        try {
            Scheduler scheduler = schedulerFactory.getScheduler();
            GroupMatcher<JobKey> matcher = GroupMatcher.groupEquals("websocket-check-job-group");
            for (JobKey key : scheduler.getJobKeys(matcher)) {
                JobDetail detail = scheduler.getJobDetail(key);
                log.info("Found job: {}", detail.getKey());//Found job: websocket-check-job-group.websocket-check-job7ef62ee1-a030-49bb-a4ec-1bd3144a05e1
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
    /**
     * 查看指定的JobDetail是否存在
     */
    public static boolean isExistJob(Long userId,Scheduler scheduler) {
        try {
            GroupMatcher<JobKey> matcher = GroupMatcher.groupEquals("websocket-check-job-group");
            for (JobKey key : scheduler.getJobKeys(matcher)) {
                JobDetail detail = scheduler.getJobDetail(key);
                log.info("Found job: {}", detail.getKey());//Found job: websocket-check-job-group.websocket-check-job101
                if (("websocket-check-job-group.websocket-check-job"+userId).equals(detail.getKey().toString())){
                    log.debug("该用户已存在任务");
                    return true;
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 取消指定的JobDetail及其关联的Trigger
     * @param jobName 任务名称
     */
    public static void cancelJob(String jobName) {
        StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
        try {
            Scheduler scheduler = schedulerFactory.getScheduler();
            JobKey jobKey = JobKey.jobKey(jobName, "websocket-check-job-group");
            boolean deleted = scheduler.deleteJob(jobKey);
            if (deleted) {
                log.info("Deleted job: {}", jobKey);
            } else {
                log.warn("Failed to delete job: {}", jobKey);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}